package com.ys.arr;

/**
 * @author CodeYang
 * @Description 实现数组的反转:
 * 将数组反序输出，原数组{5, 12, 90, 18, 77, 76, 45, 28, 59, 72}，
 * 反转后为{72,59,28,45,76,77,18, 90,12,5}。
 * 数组和循环的使用注意事项:
 * 1: 要减少使用arr.length  因为:每次调用length 其实都是执行遍历一遍数组长度,在返回,
 * 一般建议使用 变量接收arr.length
 * 2:
 * 3:不要在循环中定义新变量,来参与操作,因为这样比较浪费存储空间,如果有需要建议在循环外面定义变量,并初始化
 * @Date 2020/12/9 15:37
 */
public class 数组的反转 {
    public static void main(String[] args) {
        int[] arr = {5, 12, 90, 18, 77, 76, 45, 28, 59, 72};
        System.out.println("反转数组");
//        arr = inversionArray01(arr);
        inversionArray02(arr);
        // 遍历输出
        for (int i : arr) {
            System.out.println(i);
        }
    }

    /**
     * 反转数组元素
     * 核心: 反转规则:
     * 1:新数组 倒序接收 原数组 元素值,
     * oldArr[]----实际长度为8 length =8
     * 2: newArr[0] = oldArr[7]
     * newArr[1] = oldArr[6]
     * .......
     * newArr[7] = oldArr[0]
     * 规律: newArr[i]=oldArr[8-1-i]
     *
     * @param oldArr int []原数组
     * @return int [] 新数组 老
     */
    static int[] inversionArray01(int[] oldArr) {
        // 1创建新数组
        int[] newArr = new int[oldArr.length];
        // 2 反转数组
        for (int i = 0; i < oldArr.length; i++) {
            //新数组反序接收 原数组元素
            //  newArr[i] = oldArr[oldArr.length - 1 - i];
            newArr[oldArr.length - 1 - i] = oldArr[i];
        }
        return newArr;
    }

    /**
     * 反转数组2:
     * 首尾交换数组反转:
     * 不管是奇数还是偶数, 都只需要遍历 len/2 次, 奇数时,中间数根本取不到,也不会改变;
     * 空杯模型,一加两减,异或运算
     * 首尾交换规律: 也是大部分的倒序规律
     * i = len -x(x为固定值)-i
     *
     * @param arr 原数组
     *            注意:这里没有返回值:  因为这里传递的时引用数据类型,直接更改了head堆内存中,数组的值,不需要在返回了
     */
    static void inversionArray02(int[] arr) {
        int len = arr.length;
        int temp = 0;
        // 1.通过for循环，遍历数组前半区的所有元素
        for (int i = 0; i < len / 2; i++) {
            // 2.首尾元素交换位置，arr[i]和arr[arr.length-1-i]交换位置
            temp = arr[i];
            arr[i] = arr[len - 1 - i];
            arr[len - 1 - i] = temp;
        }

    }


}
